unit uToast;

interface

uses
  Windows, Classes, Messages, SysUtils, Graphics,
  Controls, Forms, StdCtrls, ExtCtrls, Clipbrd;

type
  TToast = class
  private
    class procedure DoDbClick(Sender: TObject);
    class procedure DoClick(Sender: TObject);
    class procedure DoTimer(Sender: TObject);
  public
    class procedure Toast(Form: TCustomForm; const Msg: string; ATimeOut: Integer = 3000;
      const bgColor: TColor = clGray; const txtColor: TColor = clWhite);
  end;

implementation

{ TToast }

class procedure TToast.DoClick(Sender: TObject);
begin
  if Sender is TLabel then
    Clipboard.AsText := TLabel(Sender).Caption;
end;

class procedure TToast.DoDbClick(Sender: TObject);
var
  Pnl: TWinControl;
begin
  if Sender is TPanel then Pnl := TWinControl(Sender)
  else if Sender is TLabel then Pnl := TLabel(Sender).Parent;
  TTimer(Pointer(Pnl.Tag)).Free;
  Pnl.Parent.RemoveControl(Pnl);
  FreeAndNil(Pnl);
end;

class procedure TToast.DoTimer(Sender: TObject);
var
  Pnl: TWinControl;
begin
  Pnl := TWinControl(TTimer(Sender).Owner);
  Pnl.Parent.RemoveControl(Pnl);
  FreeAndNil(Pnl);
end;

class procedure TToast.Toast(Form: TCustomForm; const Msg: string;
  ATimeOut: Integer; const bgColor, txtColor: TColor);
var
  Pnl: TPanel;
  lMsg: TLabel;
  lTimer: TTimer;
  R: TRect;
  rgn :Thandle;
begin
  Pnl := TPanel.Create(Form);
  Pnl.Visible := False;
  Pnl.Parent := Form;
  Pnl.ParentCtl3D := False;
  Pnl.ParentColor := False;
  Pnl.ParentBackground := False;
  Pnl.Ctl3D := False;
  Pnl.Caption := '';
  Pnl.BorderStyle := bsSingle;
  Pnl.Font.Size := 10;
  Pnl.Font.Color := txtColor;
  Pnl.BevelOuter := bvNone;
  Pnl.Padding.SetBounds(10, 5, 10, 6);
  Pnl.AutoSize := True;
  Pnl.DoubleBuffered := True;
  Pnl.FullRepaint := True;
  Pnl.Color := bgColor;
  Pnl.Anchors := [akLeft, akBottom];
  lMsg := TLabel.Create(Pnl);
  lMsg.Parent := Pnl;
  lMsg.Caption := Msg;
  lMsg.Transparent := True;
  lMsg.AutoSize := True;
  lMsg.ShowAccelChar := False;
  Pnl.Top := -1000;
  Pnl.Visible := True;
  Pnl.Realign;
  R := Pnl.ClientRect;
  rgn := CreateRoundRectRgn(R.Left, R.Top, R.Right, R.Bottom, 5, 5);
  Form.Perform(EM_GETRECT, 0, lParam(@r));
  InflateRect(r, -5, -5);
  Form.Perform(EM_SETRECTNP, 0, lParam(@r));
  SetWindowRgn(Pnl.handle, rgn, true);
  R := Form.ClientRect;
  Pnl.Left := R.Left + (R.Width - Pnl.Width) div 2;
  Pnl.Top := R.Bottom - Pnl.Height - 32;
  Pnl.BringToFront;
  Pnl.Invalidate;

  Pnl.OnDblClick := DoDbClick;
  lMsg.OnDblClick := DoDbClick;
  lMsg.OnClick := DoClick;

  lTimer := TTimer.Create(Pnl);
  lTimer.Interval := ATimeOut;
  lTimer.OnTimer := DoTimer;
  Pnl.Tag := NativeInt(lTimer);
end;

end.
